package main

import (
	"fmt"
	"sort"
	"sync"
)

/*

map是一种特殊的数据结构，一种元素对（pair）的无序集合，pair对应一个key（索引）和一个value（值），所以这个结构也称为关联数组或字典，这是一种能够快速寻找值的理想结构，给定key，就可以迅速找到对应的value。

map是引用类型，可以使用如下方式声明：

var mapname map[keytype]valuetype

--

Go语言在1.9版本中提供了一种效率较高的并发安全的sync.Map，和map不同，不是以语言原生形态提供，而是在sync包下的特殊结构。

sync.Map有以下特性：
无须初始化，直接声明即可。
不能使用map的方式进行取值和设置等操作，而是使用sync.Map的方法进行调用，Store表示存储，Load表示获取，Delete表示删除。
使用Range配合一个回调函数进行遍历操作，通过回调函数返回内部遍历出来的值，Range参数中回调函数的返回值在需要继续迭代遍历时，返回true，终止迭代遍历时，返回false。

sync.Map没有提供获取map数量的方法，替代方法是在获取sync.Map时遍历自行计算数量，sync.Map为了保证并发安全有一些性能损失，因此在非并发情况下，使用map相比使用sync.Map会有更好的性能。

*/

func main() {

	var map1 map[string]int
	var map2 = map[string]int{"k1": 1, "k2": 2}

	map1 = map2
	fmt.Println(map1)
	fmt.Println(map2)

	map3 := map[string]float32{"k1": 1.0, "k2": 4.1}
	fmt.Println(map3)

	// 添加元素
	map3["k3"] = 3.2
	fmt.Println(map3)

	// 使用make创建map
	map4 := make(map[string]float32, 16)
	fmt.Println(map4)
	fmt.Println(map4)

	// for range遍历map
	for key, value := range map3 {
		fmt.Printf("%v: %v\n", key, value)
	}

	// 排序
	var values []string
	for _, value := range map3 {
		values = append(values, fmt.Sprintf("%v", value))
	}
	fmt.Println(values)

	// 排序
	sort.Strings(values)
	fmt.Println(values)

	// 删除
	delete(map3, "k1")
	fmt.Println(map3)

	// 清空
	// Go语言中并没有为map提供任何清空所有元素的函数、方法，清空map的唯一办法就是重新make一个新的map，不用担心垃圾回收的效率，Go语言中的并行垃圾回收效率比写一个清空函数要高效的多。
	map3 = make(map[string]float32)
	fmt.Println(map3)

	// sync.Map
	var syncMap sync.Map
	syncMap.Store("k1", 1.0)
	syncMap.Store("k2", 2.1)
	syncMap.Store("k3", 3.2)

	fmt.Println(syncMap)

	// 遍历
	syncMap.Range(func(key, value interface{}) bool {
		fmt.Println(key, value)
		return true
	})

	// 删除
	syncMap.Delete("k1")
	fmt.Println(syncMap.Load("k1"))
	fmt.Println(syncMap.Load("k2"))
}
